#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
__all__ = []

from ..viewlib import canvas
import logging

Logger = logging.getLogger('PySolFC.TextLayout')

from ..settings import CONF_OPT

class TextLayout(object):

    def _get_text_size(self, text, fontname='canvas_fixed'):
        """
        _get_text_size(text:int, font:str='canvas_fixed') -> int

        Get size of canvas text.

        :param string text: text for canvas.
        :return: size of text.
        """
        text = help.split('\n')
        text.sort(key=len)
        return canvas.TextItem.get_text_width(text[-1], fontname=fontname)

    def get_text_attr(self, stack, anchor):
        """
        get_text_attr(stack:obj, anchor:str) -> tup

        Compute relative position of text label off stack.

        :param Stack stack: stack with set x, y coordinate attr.
        :param string anchor: position of text label relative stack.
        :return: tuple of offset and anchor for text labeself.
        :raises: Assertion error if anchor length not 2 or value not 'center'.

        note::
          pass 'nn' or 'ss' for anchor to increas the offset.

          top left coords (0, 0,) are used when stack is None.
        """
        assert len(anchor) < 3 or anchor == 'center'
        x, y = (0, 0,) if stack is None else (stack.x, stack.y,)
        if 'w' in anchor:  # Left of stack
            x -= self.XM
        elif 'e' in anchor:  # Right of stack
            x += self.XS  # self.CW + self.XM
        else:  # Center of Stack
            x += self.HCW
        if 'n' in anchor:  # Above stack
            y -= self.YM * (int(anchor == 'nn') + 1)
        elif 's' in anchor:  # Below stack
            y += self.CH + self.YM * (int(anchor == 'ss') + 1)
        else:  # Center of stack
            y += self.HCH
        return (x, y, {'n': 's', 'nn': 's', 'nw': 'ne', 'ne': 'nw',
                       'sw': 'se', 'se': 'sw', 'w': 'e', 'w': 'e',
                      }.get(anchor, 'n'),)

    def create_help_text(self, stack, anchor, dx=0, dy=0, text=''):
        """
        create_help_text(stack:obj, anchor:str, dx:int=0, dy:int=0,
          text:str='') -> obj

        Create TextItem label of text relative to stack for use with
        Game.texts.help. Label should contain important game assistance.

        :param Stack stack: stack with set x, y coordinate attr.
        :param string anchor: position of text label relative stack.
        :keyword integer dx: delta x-offset.
        :keyword integer dy: delta y-offset.
        :keyword string text: init string.
        :return: canvas.TextItem

        seealso::
          get_text_attr() for use of achors 'nn', and 'ss'.
        """
        if self.canvas.preview > 1:
            return
        assert self.texts['help'] is None
        tx, ty, ta = self.get_text_attr(stack, anchor)
        return canvas.TextItem(self.canvas, (tx + dx, ty + dy), anchor=ta,
                               fontname='fixed', text=text)

    def create_score_text(self, stack, anchor, dx=0, dy=0, text=''):
        """
        create_score_text(stack:obj, anchor:str, dx:int=0, dy:int=0,
          text:str='') -> obj

        Create TextItem label of text relative to stack for use with
        Game.texts['score']. Label should be updated with current game score.

        :param Stack stack: stack with set x, y coordinate attr.
        :param string anchor: position of text label relative stack.
        :keyword integer dx: delta x-offset.
        :keyword integer dy: delta y-offset.
        :keyword string text: init string.
        :return: canvas.TextItem

        seealso::
          get_text_attr() for use of achors 'nn', and 'ss'.
        """
        if self.canvas.preview > 1:
            return
        assert self.texts['score'] is None
        tx, ty, ta = self.get_text_attr(stack, anchor)
        return canvas.TextItem(self.canvas, (tx + dx, ty + dy), anchor=ta,
                               fontname='large', text=text)

    def create_info_text(self, stack, anchor, dx=0, dy=0, text=''):
        """
        create_info_text(stack:obj, anchor:str, dx:int=0, dy:int=0,
          text:str='') -> obj

        Create TextItem label of text relative to stack for use with
        Game.texts['info']. Label should be updated with dynamic info
        for a stack group such as its base suit, base rank, or dir.

        :param Stack stack: stack with set x, y coordinate attr.
        :param string anchor: position of text label relative stack.
        :keyword integer dx: delta x-offset.
        :keyword integer dy: delta y-offset.
        :keyword string text: init string.
        :return: canvas.TextItem

        seealso::
          get_text_attr() for use of achors 'nn', and 'ss'.
        """
        if self.canvas.preview > 1:
            return
        assert self.texts['info'] is None
        tx, ty, ta = self.get_text_attr(stack, anchor)
        return canvas.TextItem(self.canvas, (tx + dx, ty + dy), anchor=ta,
                               fontname='default', text=text)

    def set_misc_text(self, stack, anchor, dx=0, dy=0, text=''):
        """
        set_misc_text(stack:obj, anchor:str, dx:int=0, dy:int=0, text:str='')
          -> None

        Set stack.texts['misc'] with TextItem label of text relative to stack.
        Label should be updated with dynamic info for a stack such as its base
        suit, base rank, or dir.

        :param Stack stack: stack with set x, y coordinate attr.
        :param string anchor: position of text label relative stack.
        :keyword integer dx: delta x-offset.
        :keyword integer dy: delta y-offset.
        :keyword string text: init string.

        seealso::
          get_text_attr() for use of achors 'nn', and 'ss'.
        """
        if self.canvas.preview > 1:
            return
        assert stack.texts['misc'] is None
        tx, ty, ta = self.get_text_attr(stack, anchor)
        stack.texts['misc'] = canvas.TextItem(self.canvas, (tx + dx, ty + dy),
                                       anchor=ta, text=text, fontname='default')

    def set_ncards_text(self, stack, anchor, dx=0, dy=0, text_format='%d'):
        """
        set_ncards_text(stack:obj, anchor:str, dx:int=0, dy:int=0,
          text_format:str='') -> None

        Set stack.texts['ncards'] with TextItem label relative to stack. Label
        should be updated with dynamic info for the stack's number of cards in
        text_format.

        :param Stack stack: stack with set x, y coordinate attr.
        :param string anchor: position of text label relative stack.
        :keyword integer dx: delta x-offset.
        :keyword integer dy: delta y-offset.
        :keyword string text: init string.

        seealso::
          get_text_attr() for use of achors 'nn', and 'ss'.
        """
        if self.canvas.preview > 1:
            return
        assert stack.texts['ncards'] is None
        tx, ty, ta = self.get_text_attr(stack, anchor)
        stack.texts['ncards'] = canvas.TextItem(self.canvas, (tx + dx, ty + dy),
                                             fontname='default', anchor=ta)
        stack.texts['ncards'].text_format = text_format

    def set_rounds_text(self, stack, anchor, dx=0, dy=0, always=False):
        """
        set_rounds_text(stack:obj, anchor:str, dx:int=0, dy:int=0,
          text_format:str='') -> None

        Set stack.texts['rounds'] with TextItem label relative to stack. Label
        should be updated with dynamic info for the curent round of game play.

        :param Stack stack: stack with set x, y coordinate attr.
        :param string anchor: position of text label relative stack.
        :keyword integer dx: delta x-offset.
        :keyword integer dy: delta y-offset.
        :keyword string text: init string.

        note::
          pass 'nnn' or 'sss' for anchor to further increase the offset by
          TEXT_MARGIN. 'nn' or 'ss' will be passed to get_text_attr().

        seealso::
          get_text_attr() for use of achors 'nn', and 'ss'.
        """
        if self.canvas.preview > 1:
            return
        assert stack.texts['rounds'] is None
        if (hasattr(stack, 'max_rounds') and not always and
            stack.max_rounds <= 1):
            return
        if anchor == 'nnn':
            anchor = 'nn'
            dy -= -self.TEXT_MARGIN
        elif anchor == 'sss':
            anchor = 'ss'
            dy += self.TEXT_MARGIN
        tx, ty, ta = self.get_text_attr(stack, anchor)
        stack.texts['rounds'] = canvas.TextItem(self.canvas, (tx + dx, ty + dy),
                                             fontname=('default'), anchor=ta)